package com.ruoyi.util;

import com.jcraft.jsch.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 文件上传工具类
 * 用于将文件上传到远程服务器
 */
public class FileUploadUtil {

    /**
     * 通过SFTP上传文件到远程服务器（使用传入的配置参数）
     *
     * @param host 远程服务器地址
     * @param port SSH端口
     * @param username 用户名
     * @param password 密码
     * @param remoteBasePath 远程服务器基础路径
     * @param file 要上传的文件
     * @param module 模块名称（用于创建子目录）
     * @return 文件访问URL
     * @throws Exception 上传异常
     */
    public static String uploadFileToRemoteServer(String host, int port, String username,
                                                  String password, String remoteBasePath,
                                                  MultipartFile file, String module) throws Exception {
        JSch jsch = new JSch();
        Session session = null;
        ChannelSftp sftpChannel = null;

        try {
            // 建立SSH连接
            session = jsch.getSession(username, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(30000); // 30秒超时

            // 打开SFTP通道
            sftpChannel = (ChannelSftp) session.openChannel("sftp");
            sftpChannel.connect(30000); // 30秒超时

            // 生成远程文件路径
            String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String remoteDir = remoteBasePath + module + "/" + datePath;
            String remoteFilePath = remoteDir + "/" + file.getOriginalFilename();

            // 创建远程目录（递归创建）
            createRemoteDirs(sftpChannel, remoteDir);

            // 上传文件
            InputStream inputStream = file.getInputStream();
            sftpChannel.put(inputStream, remoteFilePath);
            inputStream.close();

            // 构造可访问的URL (根据实际情况调整URL格式)
            String fileUrl = "http://" + host + ":8488/riverFiles/" + module + "/" + datePath + "/" + file.getOriginalFilename();


            return fileUrl;

        } finally {
            // 关闭连接
            if (sftpChannel != null && sftpChannel.isConnected()) {
                sftpChannel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

    /**
     * 通过SFTP上传文件到远程服务器（使用配置类）
     *
     * @param sftpConfig SFTP配置信息
     * @param file 要上传的文件
     * @param module 模块名称（用于创建子目录）
     * @return 文件访问URL
     * @throws Exception 上传异常
     */
    public static String uploadFileToRemoteServer(SftpConfig sftpConfig,
                                                  MultipartFile file, String module) throws Exception {
        return uploadFileToRemoteServer(
                sftpConfig.getHost(),
                sftpConfig.getPort(),
                sftpConfig.getUsername(),
                sftpConfig.getPassword(),
                sftpConfig.getPath(),
                file,
                module
        );
    }

    /**
     * 递归创建远程目录
     *
     * @param sftpChannel SFTP通道
     * @param dirPath 目录路径
     * @throws SftpException SFTP异常
     */
    private static void createRemoteDirs(ChannelSftp sftpChannel, String dirPath) throws SftpException {
        String[] folders = dirPath.split("/");
        StringBuilder path = new StringBuilder();

        for (String folder : folders) {
            if (folder.length() > 0) {
                path.append("/").append(folder);
                try {
                    sftpChannel.cd(path.toString());
                } catch (SftpException e) {
                    // 目录不存在，创建目录
                    sftpChannel.mkdir(path.toString());
                    sftpChannel.cd(path.toString());
                }
            }
        }
    }

    /**
     * SFTP配置信息类
     */
    @Setter
    @Getter
    public static class SftpConfig {
        private String host;
        private int port;
        private String username;
        private String password;
        private String path;

        public SftpConfig(String host, int port, String username, String password, String path) {
            this.host = host;
            this.port = port;
            this.username = username;
            this.password = password;
            this.path = path;
        }

    }
}
